import math
from typing import Union
from pyecharts.faker import Faker
from pyecharts import options as opts
from pyecharts.charts import Bar, Line
import json
import random
import threading
import time
from flask import Blueprint, Flask, request, jsonify
from flask_sock import Sock
from element_sci_api import (
    DynamicEChartComponent,
    DynamicForm,
    ParamsManager,
    IntParam,
    ArrayParam,
    LocalDirectorySelector,
    SciApp,
    DraggingCanvas,
    DataVisualizationLargeScreen,
    TableBrowserComponent,
    QueriedData
)


def print_routes(app):
    with app.test_request_context():
        print("Available routes:")
        for rule in app.url_map.iter_rules():
            print(f"{rule.endpoint}: {rule.rule}")


app = Flask(__name__)
sock = Sock(app)


class MyDynamicChartComponent(DynamicEChartComponent):
    def __init__(self, sock: Sock, rel_url: str):
        super().__init__(
            sock,
            rel_url,
            {
                "type": "initial",
                "data": {
                    "bloodPressureOption": {
                        "animation": False,
                        "title": {"text": "血压实时监测"},
                        "legend": {"data": ["收缩压", "舒张压"]},
                        "tooltip": {"trigger": "axis"},
                        "xAxis": {"type": "category", "boundaryGap": False, "data": []},
                        "yAxis": {"type": "value"},
                        "series": [
                            {
                                "name": "收缩压",
                                "type": "line",
                                "data": [],
                                "smooth": True,
                            },
                            {
                                "name": "舒张压",
                                "type": "line",
                                "data": [],
                                "smooth": True,
                            },
                        ],
                    }
                },
            },
        )
        self.th = threading.Thread(target=self.loop)
        self.th.daemon = True
        self.th.start()

    def loop(self):
        while 1:
            time.sleep(3)
            self.send_data(
                {
                    "type": "update",
                    "data": {
                        "bloodPressureOption": {
                            "series": [
                                random.random(),
                                random.random(),
                            ]
                        }
                    },
                }
            )

    def run(self):
        print("Running dynamic component")


class data:
    pass


sciapp = SciApp("./pyminer-sciapp-configs")

mydynamic: MyDynamicChartComponent = MyDynamicChartComponent(
    sock, "/dynamic_chart")
form = DynamicForm(
    app,
    "/dynamic_form",
    [
        (IntParam("param1", (1, 10), label="Param 1")),
        (
            ArrayParam(
                "param_arr",
                [
                    IntParam("param2", (1, 10)),
                    IntParam("param3", (1, 20), label="Param 3"),
                ],
                component="panel",
                label="Param 1",
            )
        ),
    ],
)
local_directory_selector = LocalDirectorySelector(
    app,
    "local-directory_selector",
)

# 可视化大屏部分


def bar_stack():
    bar = Bar(init_opts=opts.InitOpts(
        theme="light", width="1000px", height="600px"))
    bar.add_xaxis(Faker.choose())
    # stack值一样的系列会堆叠在一起
    bar.add_yaxis("A", Faker.values(), stack="stack1")
    bar.add_yaxis("B", Faker.values(), stack="stack1")
    bar.add_yaxis("C", Faker.values(), stack="stack2")
    return bar


def bar_with_visualmap_color():
    bar = Bar(init_opts=opts.InitOpts(
        theme="light", width="1000px", height="600px"))
    bar.add_xaxis(Faker.choose())
    bar.add_yaxis("A", Faker.values())
    bar.add_yaxis("B", Faker.values())
    # 设置视觉组件，默认通过颜色映射数据，数值范围为0-100，可通过min_和max_进行自定义
    bar.set_global_opts(visualmap_opts=opts.VisualMapOpts())
    return bar


x_data = [i for i in range(1, 11)]
y_data = [890] * 10
index = 4


def create_line():
    global index
    # x_data.append(index)

    y_data.append(random.randint(500, 1000))
    # if len(x_data) >= 10:
    # x_data.pop(0)
    y_data.pop(0)
    index += 1
    print(x_data, y_data)
    return (
        Line()
        .set_global_opts(
            tooltip_opts=opts.TooltipOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(type_="category"),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
        )
        .add_xaxis(xaxis_data=x_data)
        .add_yaxis(
            series_name="series_1",
            y_axis=y_data,
            label_opts=opts.LabelOpts(is_show=False),
        )
    )


def create_line_2():
    option = {
        "title": {
            "text": '第一个 ECharts 实例'
        },
        "tooltip": {},
        "xAxis": {
            "data": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
        },
        "yAxis": {},
        "series": [{
            "name": '销量',
            "type": 'line',
            "data": [5, 20, 36, 10, 10, 20],
            "itemStyle": {
                "normal": {
                    "lineStyle": {
                        "width": 2,
                        "type": 'dotted'  # //'dotted'点型虚线 'solid'实线 'dashed'线性虚线
                    }
                }
            },
        }]
    }
    return option


def data_visualization_generator():
    return {
        "chart_1": json.loads(bar_stack().dump_options()),
        "chart_2": json.loads(bar_with_visualmap_color().dump_options()),
        "chart_3": json.loads(create_line().dump_options()),
        "chart_4": create_line_2()
    }


dragging_container = DataVisualizationLargeScreen(
    "data-visualization-large-screen",
    app,
    data_visualization_generator,
    default_chart_style_options={
        "chart_4": {
            "title": {
                "text": '第一个 ECharts 实例'
            },
            "series": [{
                "name": '销量',
                "itemStyle": {
                    "normal": {
                        "lineStyle": {
                            "width": 2,
                            "type": 'dotted'  # //'dotted'点型虚线 'solid'实线 'dashed'线性虚线
                        }
                    }
                },
            }]
        },
        "chart_3": {
            "animation": False,
            "title": {"text": "AAAAAAA"},
            "series": [
                {
                    "smooth": True,
                    # "itemStyle": {  # 点的颜色配置
                    #     "color": "#ff0000"
                    # },
                    "lineStyle": {  # 线条的颜色配置
                        "color": "#0000ff",
                        "width": 4,
                        "type": 'dashed'
                    }
                }
            ]
        }
    }
)


class MyTableBrowser(TableBrowserComponent):
    def __init__(self, component_name: str, service: Union[Flask, Blueprint]) -> None:
        super().__init__(component_name, service)
        self.data = [
            {"name": f"bob_{i}", "age": i} for i in range(100)
        ]

    def get_table_names(self):
        return ["hello", "aaaaa", "bbbbbb"]

    def query_data(self, args: dict) -> QueriedData:
        page, page_size = int(args["page"]), int(args["pageSize"])
        # 根据page和page_size从self.data中获取数据
        start_idx = (page - 1) * page_size
        end_idx = min(start_idx + page_size, len(self.data))
        # total_pages = math.ceil(len(self.data) / page_size)
        return QueriedData(len(self.data), self.data[start_idx:end_idx],  [{"name": "name", "type": "string"}, {"name": "age", "type": "int"}]
                           ).to_dict()


table_browser = MyTableBrowser("db_browser", app)
if __name__ == "__main__":
    print_routes(app)
    app.run(port=5000, host="0.0.0.0")
